package com.idanchuang.component.webflux.log;

import ch.qos.logback.classic.AsyncAppender;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
import com.idanchuang.component.core.ServiceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;

/**
 * 访问日志打印Logger
 */
public class AccessLogger {

    private static final Logger logger;

    private static final String APPENDER_NAME = "DC_WEB_ACCESS";
    private static final String PATTERN = "%msg%n";
    private static final Level LEVEL = Level.INFO;

    private static final String ENV_LOG_RT_KEY = "ACG_LOG_RT";
    private static final String ENV_HOME_KEY = "HOME";

    /** 可通过环境变量自定义文件 (-Dsun.access.file=/data/xxx/access1.log)  */
    private static final String PROPERTY_FILE = "dc.access.file";

    //在类加载时执行，保证执行一遍，不在执行，保证单实例。
    static {
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        FileAppender<ILoggingEvent> appender = new FileAppender<>();
        appender.setContext(loggerContext);
        appender.setAppend(true);
        appender.setName(APPENDER_NAME);
        // 指定路径优先
        String file = System.getProperty(PROPERTY_FILE, System.getenv(PROPERTY_FILE));
        if (file == null) {
            String logRt = System.getenv(ENV_LOG_RT_KEY);
            if (logRt == null) {
                logRt = System.getenv(ENV_HOME_KEY);
            }
            file = logRt + "/logs/" + ServiceInfo.getAppId() + "/access.log";
        }
        appender.setFile(file);
        //内容配置
        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
        encoder.setPattern(PATTERN);
        encoder.setCharset(StandardCharsets.UTF_8);
        encoder.setContext(loggerContext);
        encoder.start();
        appender.setEncoder(encoder);
        appender.start();

        // make it async, yeah
        AsyncAppender asyncAppender = new AsyncAppender();
        asyncAppender.setName("ASYNC_" + APPENDER_NAME);
        asyncAppender.setContext(appender.getContext());
        asyncAppender.addAppender(appender);
        // do not discard any log
        asyncAppender.setDiscardingThreshold(0);
        asyncAppender.start();

        ch.qos.logback.classic.Logger rootLogger = loggerContext.getLogger(AccessLogger.class);
        rootLogger.setLevel(LEVEL);
        rootLogger.addAppender(asyncAppender);
        rootLogger.setAdditive(false);
        logger = rootLogger;
    }

    /**
     * 打印info日志
     * @param message ..
     */
    public static void info(Object message) {
        if (logger == null) {
            return;
        }
        logger.info("{}", message);
    }

}
